アプリケーションの起動時に各ノードをすべて生成するのではなく、ユーザーがノードを展開すると、オンデマンドでノードにデータが挿入される遅延ロードという技術を使用することができます。これにより、アプリケーションの読み込み速度が向上し、リソースを効率よく使用できます。
ノードの遅延ロードを実装するには、次のコードを使用します。
Visual Basic コードの書き方
Visual Basic |
コードのコピー
|
---|---|
Public Sub New() InitializeComponent() ' ここは変更しません ' ... ' C1TreeView を初期化します InitializeTreeView() End Sub Private Sub InitializeTreeView() ' 設計時に追加された項目を削除します _tv.Items.Clear() ' アセンブリ内のすべての型をスキャンします For Each t As Type In _tv.[GetType]().Assembly.GetTypes() If t.IsPublic AndAlso Not t.IsSpecialName AndAlso Not t.IsAbstract Then ' この型のノードを追加します Dim node As New C1TreeViewItem() node.Header = t.Name node.FontWeight = FontWeights.Bold _tv.Items.Add(node) ' プロパティ、イベント、およびメソッドのサブノードを追加します node.Items.Add(CreateMemberNode("Properties", t, MemberTypes.[Property])) node.Items.Add(CreateMemberNode("Events", t, MemberTypes.[Event])) node.Items.Add(CreateMemberNode("Methods", t, MemberTypes.Method)) End If Next End Sub Private Function CreateMemberNode(header As String, memberTypes As MemberTypes) As C1TreeViewItem ' ノードを作成します Dim node As New C1TreeViewItem() node.Header = header node.Foreground = New SolidColorBrush(Colors.DarkGray) ' ノードを展開する前にノードにデータを挿入するためのイベントハンドラを登録します AddHandler node.Expanding, AddressOf node_Expanding ' ノードにデータを挿入するために必要な情報を保存します node.Tag = memberTypes ' このノードを展開できるように、ダミーノードを追加します node.Items.Add(New C1TreeViewItem()) node.IsExpanded = False ' 終了します Return node End Function 'ノードにデータを挿入します Private Sub node_Expanding(sender As Object, e As RoutedEventArgs) ' イベントが発生したノードを取得します Dim node As C1TreeViewItem = TryCast(sender, C1TreeViewItem) ' イベントハンドラの登録を解除します(ノードにデータを挿入したら、このハンドラは不要になります) RemoveHandler node.Expanding, AddressOf node_Expanding ' ダミーノードを削除します node.Items.Clear() ' ノードにデータを挿入します Dim type As Type = DirectCast(node.Parent.Tag, Type) Dim memberTypes As MemberTypes = DirectCast(node.Tag, MemberTypes) Dim bf As BindingFlags = BindingFlags.[Public] Or BindingFlags.Instance For Each mi As MemberInfo In type.GetMembers(bf) If mi.MemberType = memberTypes Then If Not mi.Name.StartsWith("get_") AndAlso Not mi.Name.StartsWith("set_") Then Dim item As New C1TreeViewItem() item.Header = mi.Name item.FontSize = 12 node.Items.Add(item) End If End If Next End Sub |
C# コードの書き方
C# |
コードのコピー
|
---|---|
public Page() { InitializeComponent(); // ここは変更しません // ... // C1TreeView を初期化します InitializeTreeView(); } void InitializeTreeView() { // 設計時に追加された項目を削除します _tv.Items.Clear(); // アセンブリ内のすべての型をスキャンします foreach (Type t in _tv.GetType().Assembly.GetTypes()) { if (t.IsPublic && !t.IsSpecialName && !t.IsAbstract) { // この型のノードを追加します C1TreeViewItem node = new C1TreeViewItem(); node.Header = t.Name; node.FontWeight = FontWeights.Bold; _tv.Items.Add(node); // プロパティ、イベント、およびメソッドのサブノードを追加します node.Items.Add(CreateMemberNode("Properties", t, MemberTypes.Property)); node.Items.Add(CreateMemberNode("Events", t, MemberTypes.Event)); node.Items.Add(CreateMemberNode("Methods", t, MemberTypes.Method)); } } } C1TreeViewItem CreateMemberNode(string header, MemberTypes memberTypes) { // ノードを作成します C1TreeViewItem node = new C1TreeViewItem(); node.Header = header; node.Foreground = new SolidColorBrush(Colors.DarkGray); // ノードを展開する前にノードにデータを挿入するためのイベントハンドラを登録します node.Expanding += node_Expanding; // ノードにデータを挿入するために必要な情報を保存します node.Tag = memberTypes; // このノードを展開できるように、ダミーノードを追加します node.Items.Add(new C1TreeViewItem()); node.IsExpanded = false; // 終了します return node; } //ノードにデータを挿入します void node_Expanding(object sender, RoutedEventArgs e) { // イベントが発生したノードを取得します C1TreeViewItem node = sender as C1TreeViewItem; // イベントハンドラの登録を解除します(ノードにデータを挿入したら、このハンドラは不要になります) node.Expanding -= node_Expanding; // ダミーノードを削除します node.Items.Clear(); // ノードにデータを挿入します Type type = (Type)node.Parent.Tag; MemberTypes memberTypes = (MemberTypes)node.Tag; BindingFlags bf = BindingFlags.Public | BindingFlags.Instance; foreach (MemberInfo mi in type.GetMembers(bf)) { if (mi.MemberType == memberTypes) { if (!mi.Name.StartsWith("get_") && !mi.Name.StartsWith("set_")) { C1TreeViewItem item = new C1TreeViewItem(); item.Header = mi.Name; item.FontSize = 12; node.Items.Add(item); } } } } |
この実装は、ユーザーがノードを展開しようとしたときに、ノードにデータを挿入できるように、Expanding イベントのイベントハンドラを登録します。Tag プロパティには、ノードにデータを挿入するために必要な情報を保存します。最後に、ユーザーがこのノードを展開して、ノードにデータを挿入する Expanding イベントをトリガできるように、ダミーの子ノードを追加します。
Tag プロパティを使用する代わりに、C1TreeViewItem からカスタムクラスを継承し、そのクラスにすべての遅延ロードロジックを組み込むこともできるはずです。その方が洗練された方法ですが、ではテンプレートの継承がサポートされていません。テンプレートを持つクラス(Button、C1TreeViewItem など)からクラスを継承しても、テンプレートは継承されないため、テンプレートを各自で提供する必要があります。そうしないと、その派生クラスは単に空のコントロールになります。